#include "rd522_spi.h"
#include "delay.h"

void spi1_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	SPI_InitTypeDef   SPI_InitStructure;

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RD522_SPI_CLK, ENABLE);

	GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_0);
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_0);
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_0);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;    //复用功能
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;    //推挽输出
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;    //下拉
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;    //高速
	GPIO_InitStructure.GPIO_Pin = PIN_SPI1_SCK | PIN_SPI1_MOSI | PIN_SPI1_MISO;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_SetBits(GPIOB, PIN_SPI1_SCK | PIN_SPI1_MOSI | PIN_SPI1_MISO);

	GPIO_InitStructure.GPIO_Pin = PIN_SPI1_CSN;    //配置 CSN
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    //高速
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;    //输出模式
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_SetBits(GPIOA, PIN_SPI1_CSN);

	SPI_I2S_DeInit(RD522_SPI);    //将寄存器重设为缺省值
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;    //双线双向全双工
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;    //主机模式
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;    //8 位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;    //通信空闲时 SCK 为高电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;    //第二个时钟沿捕获
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;    //软件控制 NSS
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;    //SPI 速度 8 分频
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;    //数据传输从 MSB 开始
	SPI_InitStructure.SPI_CRCPolynomial = 7;    //CRC 校验
	SPI_Init(RD522_SPI, &SPI_InitStructure);
	SPI_RxFIFOThresholdConfig(RD522_SPI, SPI_RxFIFOThreshold_QF);    //重要，把应答数据位设置为 8 位
	SPI_Cmd(RD522_SPI, ENABLE);
}

void spi_write_reg(uint8_t addr, uint8_t value)
{
    RD522_SPI_CS_LOW;  
				addr = (addr << 1) & 0x7E;                                     //写处理6bit的地址，最高位位写标志位--0
    SPI_SendData8(RD522_SPI, addr);                                  //send RD522_SPI addr data
    while(SPI_I2S_GetFlagStatus(RD522_SPI, SPI_I2S_FLAG_RXNE) == RESET);//清掉第一字节接收内容，为无效数据
    SPI_I2S_ClearFlag(RD522_SPI, SPI_I2S_FLAG_RXNE);
    SPI_ReceiveData8(RD522_SPI);                                     //not care data
    SPI_SendData8(RD522_SPI, value);
    while(SPI_I2S_GetFlagStatus(RD522_SPI, SPI_I2S_FLAG_RXNE) == RESET);
    SPI_I2S_ClearFlag(RD522_SPI, SPI_I2S_FLAG_RXNE);
    SPI_ReceiveData8(RD522_SPI);
    RD522_SPI_CS_HIGH;
	delay_us(600);
}

uint8_t spi_read_reg(uint8_t addr)
{
    uint8_t receive = 0;

    RD522_SPI_CS_LOW;  
	addr = ((addr << 1) & 0x7E) | 0x80;             //读处理6bit寄存器地址，最高位为读标志位--1
    SPI_SendData8(RD522_SPI, addr);
    while(SPI_I2S_GetFlagStatus(RD522_SPI, SPI_I2S_FLAG_RXNE) == RESET);
    SPI_I2S_ClearFlag(RD522_SPI, SPI_I2S_FLAG_RXNE);
    SPI_ReceiveData8(RD522_SPI);
    SPI_I2S_ClearFlag(RD522_SPI, SPI_I2S_FLAG_RXNE);
    SPI_SendData8(RD522_SPI, 0x00);
    while(SPI_I2S_GetFlagStatus(RD522_SPI, SPI_I2S_FLAG_RXNE) == RESET);
    SPI_I2S_ClearFlag(RD522_SPI, SPI_I2S_FLAG_RXNE);
    receive = SPI_ReceiveData8(RD522_SPI);
    RD522_SPI_CS_HIGH;

    return receive;
}

//连续读FIFO
void spi_read_fifo(uint8_t *val, uint8_t rec_len)
{
    uint8_t i = 0;
    volatile uint8_t tmpdata = 0;

    RD522_SPI_CS_LOW;  
	
    SPI_SendData8(RD522_SPI, R_FIFOADDR); 
    while(SPI_I2S_GetFlagStatus(RD522_SPI, SPI_I2S_FLAG_RXNE) == RESET);
    SPI_I2S_ClearFlag(RD522_SPI, SPI_I2S_FLAG_RXNE);
    tmpdata = SPI_ReceiveData8(RD522_SPI); //not care data
    SPI_I2S_ClearFlag(RD522_SPI, SPI_I2S_FLAG_RXNE);

    for(i = 0; i < (rec_len - 1); i++)
    {
        SPI_SendData8(RD522_SPI, R_FIFOADDR);
        while(SPI_I2S_GetFlagStatus(RD522_SPI, SPI_I2S_FLAG_RXNE) == RESET);
        SPI_I2S_ClearFlag(RD522_SPI, SPI_I2S_FLAG_RXNE);
        *(val + i) = SPI_ReceiveData8(RD522_SPI);
    }

    SPI_SendData8(RD522_SPI, 0x00);
    while(SPI_I2S_GetFlagStatus(RD522_SPI, SPI_I2S_FLAG_RXNE) == RESET);
    SPI_I2S_ClearFlag(RD522_SPI, SPI_I2S_FLAG_RXNE);
    *(val + i) = SPI_ReceiveData8(RD522_SPI);

    RD522_SPI_CS_HIGH;
}
//连续写FIFO
void spi_write_fifo(uint8_t *val, uint8_t send_len)
{
    uint8_t i = 0;
    volatile uint8_t tmpdata = 0;

    RD522_SPI_CS_LOW;  
    SPI_SendData8(RD522_SPI, W_FIFOADDR);                            //send RD522_SPI addr data
    while(SPI_I2S_GetFlagStatus(RD522_SPI, SPI_I2S_FLAG_RXNE) == RESET);//清掉第一字节接收内容，为无效数据
    SPI_I2S_ClearFlag(RD522_SPI, SPI_I2S_FLAG_RXNE);
    SPI_ReceiveData8(RD522_SPI);                                     //not care data

    for(i = 0; i < send_len; i++)
    {
        tmpdata = *(val + i);
        SPI_SendData8(RD522_SPI, tmpdata);
        while(SPI_I2S_GetFlagStatus(RD522_SPI, SPI_I2S_FLAG_RXNE) == RESET);
        tmpdata = SPI_ReceiveData8(RD522_SPI); 
    }

    RD522_SPI_CS_HIGH;
}

void spi_set_bit_mask(uint8_t reg, uint8_t mask) 
{
    int8_t  tmp;
    tmp = spi_read_reg(reg);
    spi_write_reg(reg, tmp | mask);  // set bit mask
}

void spi_clear_bit_mask(uint8_t reg, uint8_t mask) 
{
    int8_t  tmp;
    tmp = spi_read_reg(reg);
    spi_write_reg(reg, tmp & ~mask);  // clear bit mask
}
